package com.itlong.cloud.property.service.impl;

import com.itlong.cloud.POJO.DTO.app.APPServiceGetRepairListDTO;
import com.itlong.cloud.POJO.DTO.app.APPServiceUploadRepairDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyRepairGetRepairsByPageDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyRepairHandleDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.app.AppRepairDetailVO;
import com.itlong.cloud.POJO.VO.property.PropertyRepairGetOneVO;
import com.itlong.cloud.POJO.VO.property.PropertyRepairGetRepairsByPageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.property.dao.IRepairProcessDao;
import com.itlong.cloud.property.service.IPropertyRepairManageService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <desc>
 *     物业-物业报修管理服务层接口实现类
 * </desc>
 *
 * @createDate 2018/08/09
 */
@Service
public class PropertyRepairManageServiceImpl implements IPropertyRepairManageService {

    @Autowired
    private IRepairProcessDao iRepairProcessDao;

//    @Autowired
//    private IPropertyPaymentManageDao iPropertyPaymentManageDao;

    @Autowired
    private RedisService redisService;

    /**
     * <desc>
     *      提交物业报修申请
     * </desc>
     *
     * @param appServiceUploadRepairDTO 提交物业报修申请参数
     * @return 添加条数
     * @author wangzhi
     * @createDate 2018/08/09
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer uploadRepair(APPServiceUploadRepairDTO appServiceUploadRepairDTO) throws Exception {
        Date nowTime = new Date();
        RepairProcessPO repairProcessPO = new RepairProcessPO();
        repairProcessPO.setRepairId(LogicIdUtil.bussinessId());
        repairProcessPO.setRepairNum(appServiceUploadRepairDTO.getRepairNum());
        repairProcessPO.setProjectId(appServiceUploadRepairDTO.getProjectId());
        repairProcessPO.setRepairType(appServiceUploadRepairDTO.getRepairType());
        repairProcessPO.setRepairDescription(appServiceUploadRepairDTO.getContent());
        RoomInfoPO roomInfoPO = iRepairProcessDao.getBuildIdAndUnitId(appServiceUploadRepairDTO.getRoomId());
        if(roomInfoPO!=null){
            repairProcessPO.setBuildId(roomInfoPO.getBuildId());
            repairProcessPO.setUnitId(roomInfoPO.getUnitId());
            repairProcessPO.setRoomId(appServiceUploadRepairDTO.getRoomId());
        }
        repairProcessPO.setAppUserId(appServiceUploadRepairDTO.getAppUserId());
        repairProcessPO.setAcceptStatus(1);
        repairProcessPO.setAppointmentTime(appServiceUploadRepairDTO.getOrderDate());
        repairProcessPO.setRepairTime(nowTime);
        repairProcessPO.setRepairPicture(appServiceUploadRepairDTO.getRepairPicture());
        repairProcessPO.setRepairStatus(1);
        repairProcessPO.setStatus(DataStatusEnum.NORMAL.getType());
        repairProcessPO.setCreateTime(nowTime);
        repairProcessPO.setUpdateTime(nowTime);
        return iRepairProcessDao.save(SqlUtil.durableData(repairProcessPO,PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      获取当天已有的流水号
     * </desc>
     *
     * @param timeNum 当天的时间
     * @return 流水号集合
     * @author wangzhi
     * @createDate 2018/08/10
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getRepairNums(String timeNum) throws Exception {
        return iRepairProcessDao.getRepairNums(timeNum);
    }

    /**
     * <desc>
     *      获取我的物业报修数据
     * </desc>
     *
     * @param appServiceGetRepairListDTO 获取我的物业报修数据请求参数
     * @return 结果集
     * @author wangzhi
     * @createDate 2018/08/10
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<RepairProcessPO> getRepairList(APPServiceGetRepairListDTO appServiceGetRepairListDTO) throws Exception {
        Map<String ,Object> params = SqlUtil.convertBeanToMapParams(appServiceGetRepairListDTO);
        return iRepairProcessDao.getRepairList(params);
    }

    /**
     * <desc>
     *      获取我的报修详情
     * </desc>
     *
     * @param messageId 报修数据id
     * @return 报修管理实体对象
     * @author wangzhi
     * @createDate 2018/08/10
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public AppRepairDetailVO getRepairDetail(String messageId) throws Exception {
        AppRepairDetailVO appRepairDetailVO = iRepairProcessDao.getRepairDetail(messageId);
        RepairProcessPO repairInfo = iRepairProcessDao.getOneRepairInfo(messageId, "");
        if (StringUtils.isNotBlank(repairInfo.getServicemanUserId())) {
            List<String> servicemanUserIds = StringHandlerUtil.splitStringList(repairInfo.getServicemanUserId());
            String servicemanName = "";
//            String servicemanPhoneNum = "";
            for (String servicemanUserId : servicemanUserIds) {
                PropertyUserInfoPO propertyUserInfoPO = iRepairProcessDao.getUserNameAndPhoneNum(servicemanUserId);
                if ("".equals(servicemanName)) {
                    servicemanName += StringUtils.isNotBlank(propertyUserInfoPO.getRealName()) ? propertyUserInfoPO.getRealName() : propertyUserInfoPO.getUserName();
                } else {
                    servicemanName += ("," + (StringUtils.isNotBlank(propertyUserInfoPO.getRealName()) ? propertyUserInfoPO.getRealName() : propertyUserInfoPO.getUserName()));
                }
//                if (StringUtils.isNotBlank(propertyUserInfoPO.getPhoneNum())) {
//                    if ("".equals(servicemanPhoneNum)) {
//                        servicemanPhoneNum += propertyUserInfoPO.getPhoneNum();
//                    } else {
//                        servicemanPhoneNum += ("," + propertyUserInfoPO.getPhoneNum());
//                    }
//                }
            }
            appRepairDetailVO.setRepairMen(servicemanName);
//            appRepairDetailVO.setContactInfo(servicemanPhoneNum);
        }
        return appRepairDetailVO;
    }

    /**
     * <desc>
     *      操作报修数据
     * </desc>
     *
     * @param messageId 报修数据id
     * @param managerType 操作类型
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/13
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer repairManager(String messageId, String managerType) throws Exception {
        Date nowTime = new Date();
        // 因用户和管理员可能都对数据进行操作，故操作之前应该校验
        RepairProcessPO repairProcessPO = iRepairProcessDao.getOneRepairInfo(messageId,"");
        switch (managerType) {
            case "1":
                if (repairProcessPO != null && repairProcessPO.getRepairStatus() == 1) {
                    repairProcessPO.setRepairStatus(4);
                    repairProcessPO.setCancelTime(nowTime);
                    repairProcessPO.setUpdateTime(nowTime);
                } else {
                    return -1;
                }
                break;
            case "2":
                if (repairProcessPO != null && repairProcessPO.getRepairStatus() == 2) {
                    repairProcessPO.setAcceptStatus(2);
                    repairProcessPO.setUpdateTime(nowTime);
                } else {
                    return -1;
                }
                break;
            case "4":
                if (repairProcessPO != null && repairProcessPO.getRepairStatus() == 3 && repairProcessPO.getRepairType() == 1) {
                    repairProcessPO.setReworkStatus(1);
                    repairProcessPO.setReworkYet(0);
                    repairProcessPO.setUpdateTime(nowTime);
                } else {
                    return -1;
                }
                break;
            case "5":
                if (repairProcessPO != null && repairProcessPO.getRepairStatus() == 4) {
//                    repairProcessPO.setStatus(0);
//                    repairProcessPO.setUpdateTime(nowTime);
                    List<String> repairIds = new ArrayList<>();
                    repairIds.add(messageId);
                    return iRepairProcessDao.batchDeleteByApp(repairIds);
                } else {
                    return -1;
                }
            default:
                return 0;
        }
        Map<String, Object> map = SqlUtil.durableData(repairProcessPO, PlatformConstants.TABLE_UPDATE);
        return iRepairProcessDao.repairManager(map);
    }

    /**
     * <desc>
     *      报修数据完成付款
     * </desc>
     *
     * @param feeId 缴费账单id
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/13
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer completePay(String feeId) throws Exception {
        Date nowTime = new Date();
        // 因用户和管理员可能都对数据进行操作，故操作之前应该校验
        RepairProcessPO repairProcessPO = iRepairProcessDao.getOneRepairInfo("",feeId);
        if (repairProcessPO != null && repairProcessPO.getRepairStatus() == 2) {
            repairProcessPO.setRepairStatus(3);
            repairProcessPO.setCompleteTime(nowTime);
            repairProcessPO.setUpdateTime(nowTime);
            return iRepairProcessDao.repairManager(SqlUtil.durableData(repairProcessPO, PlatformConstants.TABLE_UPDATE));
        }
        return null;
    }

    /**
     * <desc>
     *      分页获取报修管理信息，包含待受理、已受理、已完成、已取消
     * </desc>
     *
     * @param propertyRepairGetRepairsByPageDTO 查询参数
     * @return 分页数据
     * @author wangzhi
     * @createDate 2018/08/14
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyRepairGetRepairsByPageVO> getRepairsByPage(PropertyRepairGetRepairsByPageDTO propertyRepairGetRepairsByPageDTO) throws Exception {
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyRepairGetRepairsByPageDTO);
        Page<PropertyRepairGetRepairsByPageVO> page = new Page<>();
        page.getPage().setPageSize(propertyRepairGetRepairsByPageDTO.getPageSize());
        page.getPage().setCurrentPage(propertyRepairGetRepairsByPageDTO.getCurrentPage());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<PropertyRepairGetRepairsByPageVO> datas = iRepairProcessDao.getRepairsByPage(params);
        page.setRows(datas,iRepairProcessDao.getRepairsRecordCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取单个报修信息
     * </desc>
     *
     * @param repairId 报修id
     * @return 单个报修信息对象
     * @author wangzhi
     * @createDate 2018/08/14
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyRepairGetOneVO getOneRepair(String repairId) {
        PropertyRepairGetOneVO propertyRepairGetOneVO = iRepairProcessDao.getOneRepair(repairId);
        String servicemanUserId = propertyRepairGetOneVO.getServicemanUserId();
        if (StringUtils.isNotBlank(servicemanUserId)) {
            List<String> servicemanUserIds = StringHandlerUtil.splitStringList(servicemanUserId);
            String servicemanName = "";
            for (String userId : servicemanUserIds) {
                PropertyUserInfoPO propertyUserInfoPO = iRepairProcessDao.getUserNameAndPhoneNum(userId);
                if ("".equals(servicemanName)) {
                    servicemanName += StringUtils.isNotBlank(propertyUserInfoPO.getRealName()) ? propertyUserInfoPO.getRealName() : propertyUserInfoPO.getUserName();
                } else {
                    servicemanName += ("," + (StringUtils.isNotBlank(propertyUserInfoPO.getRealName()) ? propertyUserInfoPO.getRealName() : propertyUserInfoPO.getUserName()));
                }
            }
            propertyRepairGetOneVO.setServicemanName(servicemanName);
        }
        return propertyRepairGetOneVO;
    }

    /**
     * <desc>
     *      待受理页面处理操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer acceptRepair(PropertyRepairHandleDTO propertyRepairHandleDTO) throws Exception {
        Date nowTime = new Date();
        RepairProcessPO repairInfo = iRepairProcessDao.getOneRepairInfo(propertyRepairHandleDTO.getRepairId(), "");
        if (repairInfo != null && repairInfo.getRepairStatus() == 1) {
//            PropertyUserInfoPO propertyUserInfoPO = iRepairProcessDao.getUserNameAndPhoneNum(propertyRepairHandleDTO.getLoginUserId());
//            String acceptPerson = StringUtils.isNotBlank(propertyUserInfoPO.getRealName()) ? propertyUserInfoPO.getRealName() : propertyUserInfoPO.getUserName();
            repairInfo.setRepairStatus(2);
            repairInfo.setAcceptTime(nowTime);
            repairInfo.setUpdateTime(nowTime);
            repairInfo.setAcceptPerson(propertyRepairHandleDTO.getLoginUserId());
            repairInfo.setServicemanUserId(propertyRepairHandleDTO.getServicemanUserId());
            repairInfo.setServicemanPhoneNum(propertyRepairHandleDTO.getServicemanPhoneNum());
            if (repairInfo.getRepairType() == 1) {
                // 该报修类型为个人设施，需生成账单
                PropertyPaymentBillPO propertyPaymentBillPO = new PropertyPaymentBillPO();
                propertyPaymentBillPO.setFeeId(LogicIdUtil.bussinessId());

                //生成费用单号 规则年月日+六位流水号，如180720000001
                String date = DateUtil.fomatDate(new Date(),"yyMMdd");
                //从缓存中获取流水号
                String redisKey = RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE+propertyRepairHandleDTO.getProjectId()+date;
                Integer tradeNo = (Integer)redisService.getObject(redisKey, Integer.class);
                if(tradeNo == null){
                    //查询数据库中是否有当前流水号，有的话将当前流水号放入缓存中且+1赋值给tradeNo
                    String feeNumber = iRepairProcessDao.getFeeNumberByDate(DateUtil.fomatDate(new Date(),"yyyy-MM-dd"),propertyRepairHandleDTO.getProjectId());
                    if(StringUtils.isBlank(feeNumber)){
                        tradeNo = 1;
                    }else{
                        tradeNo = Integer.valueOf(feeNumber);
                        tradeNo += 1;
                    }
                }else{
                    tradeNo+=1;
                }
                redisService.set(redisKey,RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE_TIME,tradeNo);
                propertyPaymentBillPO.setFeeNumber(date+StringHandlerUtil.autlSupply(6,tradeNo.toString(),"0"));

                propertyPaymentBillPO.setBuildId(repairInfo.getBuildId());
                propertyPaymentBillPO.setUnitId(repairInfo.getUnitId());
                propertyPaymentBillPO.setRoomId(repairInfo.getRoomId());
                AppUserInfoPO appUserInfoPO = iRepairProcessDao.getAppUserInfo(repairInfo.getAppUserId());
                propertyPaymentBillPO.setPhoneNum(appUserInfoPO.getPhoneNum());
                propertyPaymentBillPO.setRealName(appUserInfoPO.getRealName());
                Calendar cal1 = Calendar.getInstance();
                cal1.setTime(nowTime);
                cal1.set(Calendar.DAY_OF_MONTH,1);
                cal1.add(Calendar.MONTH, 0);
                propertyPaymentBillPO.setStartTime(cal1.getTime());
                Calendar cal2 = Calendar.getInstance();
                cal2.set(Calendar.DAY_OF_MONTH, cal2.getActualMaximum(Calendar.DAY_OF_MONTH));
                propertyPaymentBillPO.setEndTime(cal2.getTime());
                propertyPaymentBillPO.setType(2);
//                propertyPaymentBillPO.setPenalty(new BigDecimal(0));
                propertyPaymentBillPO.setProjectId(propertyRepairHandleDTO.getProjectId());
                propertyPaymentBillPO.setFeeStatus(1);
//                propertyPaymentBillPO.setUserId(propertyRepairHandleDTO.getLoginUserId());
                propertyPaymentBillPO.setStatus(DataStatusEnum.NORMAL.getType());
                propertyPaymentBillPO.setCreateTime(nowTime);
                propertyPaymentBillPO.setUpdateTime(nowTime);
                propertyPaymentBillPO.setPenalty(new BigDecimal(0));
                iRepairProcessDao.save(SqlUtil.durableData(propertyPaymentBillPO,PlatformConstants.TABLE_SAVE));
                repairInfo.setFeeId(propertyPaymentBillPO.getFeeId());
            }
        } else {
            return -1;
        }
        Map<String, Object> map = SqlUtil.durableData(repairInfo, PlatformConstants.TABLE_UPDATE);
        return iRepairProcessDao.repairManager(map);
    }

    /**
     * <desc>
     *      已受理页面撤销操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer cancelRepair(PropertyRepairHandleDTO propertyRepairHandleDTO) throws Exception {
        Date nowTime = new Date();
        RepairProcessPO repairInfo = iRepairProcessDao.getOneRepairInfo(propertyRepairHandleDTO.getRepairId(), "");
        if (repairInfo != null && repairInfo.getRepairStatus() == 2 && repairInfo.getAcceptStatus() == 2) {
            repairInfo.setRepairStatus(4);
            repairInfo.setCancelTime(nowTime);
            repairInfo.setUpdateTime(nowTime);
            if (StringUtils.isNotBlank(repairInfo.getFeeId())) {
                iRepairProcessDao.deletePaymentBill(repairInfo.getFeeId());
            }
        } else {
            return -1;
        }
        return iRepairProcessDao.repairManager(SqlUtil.durableData(repairInfo,PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *      已受理页面完成操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer completeRepair(PropertyRepairHandleDTO propertyRepairHandleDTO) throws Exception {
        Date nowTime = new Date();
        RepairProcessPO repairInfo = iRepairProcessDao.getOneRepairInfo(propertyRepairHandleDTO.getRepairId(), "");
        if (repairInfo != null && repairInfo.getRepairStatus() == 2 && repairInfo.getAcceptStatus() == 1) {
            repairInfo.setRepairStatus(3);
            repairInfo.setReworkYet(2);
            repairInfo.setCompleteTime(nowTime);
            repairInfo.setUpdateTime(nowTime);
            if (repairInfo.getRepairType() == 1 && repairInfo.getReworkStatus() == 0 && StringUtils.isNotBlank(repairInfo.getFeeId())) {
                if (StringUtils.isNotBlank(propertyRepairHandleDTO.getRemark())) {
                    repairInfo.setRemark(propertyRepairHandleDTO.getRemark());
                }
                PropertyPaymentBillPO propertyPaymentBillPO = iRepairProcessDao.getPaymentBill(repairInfo.getFeeId());
                propertyPaymentBillPO.setDueAmount(new BigDecimal(propertyRepairHandleDTO.getDueAmount()));
                propertyPaymentBillPO.setPaidAmount(new BigDecimal(propertyRepairHandleDTO.getDueAmount()));
                propertyPaymentBillPO.setUpdateTime(nowTime);
                iRepairProcessDao.repairManager(SqlUtil.durableData(propertyPaymentBillPO,PlatformConstants.TABLE_UPDATE));
            }
        } else {
            return -1;
        }
        return iRepairProcessDao.repairManager(SqlUtil.durableData(repairInfo,PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *      确认返修操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer reworkRepair(PropertyRepairHandleDTO propertyRepairHandleDTO) throws Exception {
        Date nowTime = new Date();
        RepairProcessPO repairInfo = iRepairProcessDao.getOneRepairInfo(propertyRepairHandleDTO.getRepairId(), "");
        if (repairInfo != null && repairInfo.getRepairStatus() == 3 && repairInfo.getRepairType() == 1 && repairInfo.getReworkStatus() == 1 && repairInfo.getReworkYet() == 0) {
            repairInfo.setRepairStatus(2);
            repairInfo.setReworkYet(1);
            repairInfo.setReworkTime(nowTime);
            repairInfo.setUpdateTime(nowTime);
        } else {
            return -1;
        }
        return iRepairProcessDao.repairManager(SqlUtil.durableData(repairInfo,PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *      批量删除
     * </desc>
     *
     * @param repairIds 报修id，多个用英文","相连
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer deleteRepairs(String repairIds) throws Exception {
        List<String> repairIdList = StringHandlerUtil.splitStringList(repairIds);
        return iRepairProcessDao.batchDeleteByProperty(repairIdList);
    }

    /**
     * <desc>
     *      依条件获取所有报修数据
     * </desc>
     *
     * @param propertyRepairGetRepairsByPageDTO 查询参数
     * @return 所有报修数据
     * @author wangzhi
     * @createDate 2018/08/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyRepairGetRepairsByPageVO> getAllRepairs(PropertyRepairGetRepairsByPageDTO propertyRepairGetRepairsByPageDTO) throws Exception {
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyRepairGetRepairsByPageDTO);
        return iRepairProcessDao.getAllRepairs(params);
    }
}
